package com.zingrow.web.base.controller;

import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.zingrow.common.ReturnStandardDataFormat;
import com.zingrow.common.utils.CommonUtils;
import com.zingrow.common.utils.JsonHelper;
import com.zingrow.common.utils.PageView;
import com.zingrow.web.base.service.impl.BaseService;
import com.zingrow.web.common.exception.AjaxBusinessException;
import com.zingrow.web.common.exception.BusinessException;
import com.zingrow.web.common.utils.SessionUtils;
import com.zingrow.web.support.operate.model.OptRecord;
import com.zingrow.web.support.operate.model.AppOptRecord;
import com.zingrow.web.support.operate.service.IOptRecordService;
import com.zingrow.web.user.model.ActiveUser;
import com.zingrow.web.user.model.User;

import net.sf.json.JSONObject;

/**
 * 控制层基类。
 * 
 * @ClassName: BaseController
 * @author seff
 * @date 2014-12-19 上午11:11:33
 */
public class BaseController {
    protected final Logger log = Logger.getLogger(getClass());

    /**
     * 添加一条操作记录 组合范例：admin 用户 添加 站点 新浪 2016-12-06 10:57:13 (其他说明)
     * 
     * @param httpRequest
     *            页面传来的request请求
     * @param optChannel
     *            操作的栏目：比如站点信息，频道信息，频道模版等
     * @param optType
     *            操作类型：新增，修改，删除等
     * @param optName
     *            操作的对象名称：如某站点信息名为：新浪
     */
  /*  public void addOptRecode(HttpServletRequest httpRequest, IOptRecordService optRecordService, String optChannel,
            String optType, String optName) {
        ActiveUser user = getUser(httpRequest);
        OptRecord optRecord = new OptRecord(null, user.getUserId(), user.getUserAccount(), optType, optChannel, optName,
                new Date());
        optRecordService.insert(optRecord);
    }*/
    //app日志写入方案
    public void addOptRecode(HttpServletRequest httpRequest, IOptRecordService optRecordService,String optChannel,String optMinChannel,String optDeed, String notes
           ) {
        ActiveUser user = getUser(httpRequest);
        String ip="";
        if(user!=null){
        AppOptRecord appOptRecord = new AppOptRecord(null, user.getUserId(), user.getUserAccount(), user.getUserName(), user.getPhoneType(),user.getPhoneSystem(),optChannel,optMinChannel, optDeed,
                new Date(),ip,notes);
        optRecordService.appInsert(appOptRecord);
        }     
    }

    /**
     * 获取session中保存的登录用户信息
     * 
     * @param request
     * @return
     */
    public ActiveUser getUser(HttpServletRequest request) {
        Subject su = SecurityUtils.getSubject();
        ActiveUser activeUser = (ActiveUser) su.getPrincipal();
        return activeUser;
    }

    /**
     * 检测用户session是否过期，如果过期，抛出对应业务异常。
     * 
     * @author seff
     * @param session
     *            HttpSession。
     * @param isAJAX
     *            是否AJAX调用。
     */
    public void checkUserTimeOut(HttpSession session, boolean isAJAX) {
        User u = SessionUtils.getUser(session);
        if (u == null) {
            if (isAJAX)
                throw new AjaxBusinessException("与服务器断开连接，请尝试重新登录。");
            else
                throw new BusinessException("与服务器断开连接，请尝试重新登录。");
        }
    }

    /**
     * 获取web应用的本地根路径。
     * 
     * @author seff
     * @param session
     *            HttpSession。
     * @return 返回web应用的本地根路径。
     */
    public String getLocalBasePath(HttpSession session) {
        return session.getServletContext().getRealPath("/");
    }

    /**
     * 获取web应用的网络根路径。
     * 
     * @author seff
     * @param request
     *            HttpServletRequest。
     * @return 返回web应用的网络根路径。
     */
    public String getWebBasePath(HttpServletRequest request) {
        String path = request.getContextPath();
        return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
    }

    /**
     * 根据数据库中资源路径，结合web应用本地 路径、web应用网络路径获取外部能访问的url。<br>
     * 1)拼装本地路径，检查文件是否存在，不存在直接返回null；<br>
     * 2)如果文件存在，根据web应用网络路径拼装外部能访问的url。
     * 
     * @author seff
     * @param request
     *            HttpServletRequest。
     * @param basePath
     *            对应资源前缀，比如用户头像，都放置在imgupload文件下，数据库中只是存里面之后的路径。
     * @param databaseFilePath
     *            数据库中存储的文件名。
     * @return 外部能访问的资源url，如果资源不存在则返回空。
     * @see BaseService#getSourceUrl(String, String, String, String)
     */
    public String getSourceUrl(HttpServletRequest request, String basePath, String databaseFilePath) {
        String sourceUrl = null;
        if (CommonUtils.isStrNotNull(databaseFilePath)
                && new File(getLocalBasePath(request.getSession()) + basePath + "\\" + databaseFilePath).exists())
            sourceUrl = (getWebBasePath(request) + basePath + "/" + databaseFilePath).replace("\\", "/");
        return sourceUrl;
    }

    /**
     * 往前端发送JSONObject类型的json数据。 通常是ajax调用后，发送返回值。
     * 
     * @param response
     *            HttpServletResponse。
     * @param jsonobject
     *            需要发送到前端的json对象。
     */
    public void sendJson(HttpServletResponse response, JSONObject jsonobject) throws IOException {
        // 在IE10以下版本，必须设置成text/html，不然传到前台，ie浏览器弹出下载保存的对话框
        // getResponse().setContentType("text/json; charset=utf-8");
        response.setContentType("text/html; charset=utf-8");
        response.setHeader("Cache-Control", "no-cache"); // 取消浏览器缓存
        response.setCharacterEncoding("utf-8");
        PrintWriter pw = response.getWriter();
        pw.print(jsonobject);
        pw.flush();
        pw.close();
    }

    protected String responseWithJson(HttpServletRequest request, Integer code, String msg, Object data,
            PageView pageView) {

        ReturnStandardDataFormat standardData = new ReturnStandardDataFormat(code, msg, data);

        if (pageView != null) {
            standardData.setPageViewParams(pageView);
        }

        standardData.setBasePath(getWebBasePath(request));

        return JsonHelper.encodeObject2Json(standardData, "yyyy-MM-dd HH:mm:ss");

    }

    protected String responseWithJson(HttpServletRequest request, Integer code, String msg, Object data) {

        return responseWithJson(request, code, msg, data, null);

    }

    protected String responseWithJson(HttpServletRequest request, Integer code, String msg) {

        return responseWithJson(request, code, msg, null, null);

    }

    /**
     * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址;
     * 
     * @param request
     * @return
     * @throws IOException
     */
    protected final String getIpAddress(HttpServletRequest request) throws IOException {
        // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
        } else if (ip.length() > 15) {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = (String) ips[index];
                if (!("unknown".equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

    /**
     * 组装返回结果和错误信息
     * 
     * @param dataFormat
     * @param type
     * @return
     */
    protected final String analyzeResult(ReturnStandardDataFormat dataFormat, int type) {
        return null;
    }

    public final String getImageRootPath(HttpServletRequest request) {
        String separator = System.getProperty("file.separator");
        String path = null;
        String imageDir = System.getProperty("imageDir");
        if (imageDir != null) {
            path = imageDir;
        } else {
            path = request.getSession().getServletContext().getRealPath(separator);
            String pPath = new File(path).getParentFile().getAbsolutePath();
            int index = pPath.lastIndexOf("wtpwebapps");
            if (index > -1) {
                pPath = pPath.substring(0,index) + "webapps";
            }
            File dir = new File(pPath, "imageDir");
            if (!dir.exists()) {
                dir.mkdirs();
            }
            path = dir.getAbsolutePath();
        }
        
        if (path.endsWith(separator)) {
            return path;
        } else {
            return path + separator;
        }

    }
    //等比切缩放图片
    public static void zoomImage(String src,String dest,int w,int h) throws Exception {
        
        double wr=0,hr=0;
        File srcFile = new File(src);
        File destFile = new File(dest);

        BufferedImage bufImg = ImageIO.read(srcFile); //读取图片
        if(bufImg.getWidth()>bufImg.getHeight())
        {
        	int v=(bufImg.getWidth()-bufImg.getHeight())/2;
        	bufImg=bufImg.getSubimage(v, 0, bufImg.getWidth()-v-v, bufImg.getHeight());
        }
        else
        {
        	int v=(bufImg.getHeight()-bufImg.getWidth())/2;
        	bufImg=bufImg.getSubimage(0, v, bufImg.getWidth(), bufImg.getHeight()-v-v);
        }
        Image Itemp = bufImg.getScaledInstance(w, h, bufImg.SCALE_SMOOTH);//设置缩放目标图片模板
        wr=w*1.0/bufImg.getWidth();     //获取缩放比例
        hr=h*1.0 / bufImg.getHeight();

        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
        Itemp = ato.filter(bufImg, null);
        try {
            ImageIO.write((BufferedImage) Itemp,dest.substring(dest.lastIndexOf(".")+1), destFile); //写入缩减后的图片
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}
